
const path     = require( "path");
const config   = require("../config");
const FileUtil = require( "./util/FileUtil");

syncAll()
	.then( startCheck )
	.catch( err => console.error( err ) );

function startCheck(  ){
	console.info( "所有文件同步完成，启动定时任务" );
	async function  doIt(  ){
		try{
			await syncRecent();

		}catch ( err ){
			console.info( err );
		}finally {
			setTimeout( doIt , 1000 * 60 );
		}

	}
	setTimeout( doIt , 1000 * 1 );
}

let lastDatePart = null ;
async function syncRecent(){
	let date = new Date();
	let datePart = parseDatePart( config.dateFolder , date );

	let sourceDir , distDir ;

	if( lastDatePart !== datePart ){
		let yesterday = new Date( date.setDate( date.getDate() -1 ) );
		let yesterdayPart = parseDatePart( config.dateFolder , yesterday );
		sourceDir = path.join(  config.source , yesterdayPart );
		distDir   = path.join(  config.dist   , yesterdayPart );
		await syncDir( sourceDir , distDir );
	}

	sourceDir = path.join(  config.source , datePart );
	distDir   = path.join(  config.dist   , datePart );

	await syncDir( sourceDir , distDir );
}

/**
 *
 * @param {String} fmt
 * @param {Date} date
 * @return {String}
 */
function parseDatePart( fmt , date ){
	return fmt.replace( /([yMd]+)/ig, function( a , $1  ){
		switch ( $1 ){
			case "yyyy":
				return date.getFullYear() ;
			case "MM" : return  to2( date.getMonth()+1);
			case "dd" : return  to2( date.getDate() );
		}
		return a;
	} );
	function to2( num  ){
		return num>9 ? num : ("0" + num );
	}
}
/**
 * 首次运行时全部同步
 * @return {Promise.<void>}
 */
async function syncAll(  ){

	if( !config.syncAll )
		return ;

	return await syncDir( config.source , config.dist  );
}

async function syncDir( sourceDir , distDir  ){

	if( !config.syncAll )
		return ;

	let sourceList = await getFilesTrim( sourceDir );
	let distList   = await getFilesTrim( distDir   );
	let distContains   = arrayToSet( distList );

	//检查源中的文件，在目标目录中是否存在
	//如同不存在或者不相同则复制到目标文件夹中
	for( let i=0; i< sourceList.length ;i++ ){

		let sourceFile = sourceList[ i ];

		let source = path.join( sourceDir , sourceFile );
		let dist   = path.join( distDir   , sourceFile );

		if( distContains[ sourceFile ] && await isTheSame( source , dist ) ){
			continue ;
		}
		console.info( "同步:" + sourceFile );
		await FileUtil.copy( source  , dist , true );
	}
}

/**
 * 比较两文件是否相同
 * @param source
 * @param dist
 * @return {Promise.<*>}
 */
async function isTheSame( source , dist  ){
	let sourceStat = await FileUtil.stat( source );
	let distStat   = await FileUtil.stat( dist   );
	if( sourceStat.size !== distStat.size )
		return false;
	if( source.mtimeMs > dist.mtimeMs ){
		return await checkContent(  source , dist) ;
	}
	return true;

}
async function checkContent(  ){
	return true;
}

function arrayToSet( list ){
	let ret = {};
	list.forEach( str => ret[ str ] = str );
	return ret;
}

/**
 *
 * @param {String} baseDir
 * @return {Promise.<Array|String|>}
 */
async function getFilesTrim( baseDir ){
	let list = await FileUtil.getFiles( baseDir );
	list = trimPath( baseDir , list );
	return list;
}

/**
 *
 * @param baseDir
 * @param list
 * @return {Array|String|{}}
 */
function trimPath( baseDir , list  ){
	let startIndex = baseDir.length;
	return list.map( item=>{
		if( ! item.startsWith( baseDir ))
			throw "路径" + item +"不是以" + baseDir +"开始";
		return item.substring( startIndex );
	});
}